//
//  main.swift
//  CaptureStyleExample
//
//  Created by jianbo.pei on 2024/1/2.
//

import Foundation


//================ 测试 start ================

capturingValueTest()

//================ 测试 end   ================


//MARK: 值捕获
func capturingValueTest() {
    capturingValue_Test1()
    capturingValue_Test2()
    capturingValue_Test3_1()
    capturingValue_Test3_2()
}

/// 1、通过 [variable1, variabla2] 的形式捕获外部变量，
///    捕获到的变量为 let 不可变类型，且捕获的是外部变量的值拷贝（编译时期即确定值，若原始变量为指针类型，那么拷贝的只是指针）
func capturingValue_Test1() {
    var a = 100
    let style1_closure = { [a] in
        /// ❎ “Left side of mutating operator isn't mutable: 'a' is an immutable capture”
//            a += 1
        print("style1:   closure = \(a)")
    }
    a += 1
    print("style1:   out 1 = \(a)")
    style1_closure()
    print("style1:   out 2 = \(a)")
    
    /**
     style1:   out 1 = 101
     style1:   closure = 100
     style1:   out 2 = 101
     */
}


/// 2、直接捕获外部变量，
///    获取的是指针，也就是说在闭包内修改变量值的话，原始变量也会被改
func capturingValue_Test2() {
    var a = 100
    let style2_closure = {
        a += 1
        print("style2:   closure = \(a)")
    }
    a += 1
    print("\n\nstyle2:   out 1 = \(a)")
    style2_closure()
    print("style2:   out 2 = \(a)")

    /**
     style2:   out 1 = 101
     style2:   closure = 102
     style2:   out 2 = 102
     */
}

/// 3、捕获的是指针类型（Class），无论是否用 [variable1] ，在闭包内对该变量进行修改，都会影响到原始变量
///
/// 3.1、用 [variable1]
func capturingValue_Test3_1() {
    let person = PC_Person()
    let style3_1_closure = { [person] in
        person.name = "AbnerPei_3.1"
        print("\n\nstyle3:   closure_3.1 = \(person.name)")
    }
    style3_1_closure()
    print("style3:   out_3.1 = \(person.name)")
    
    /**
     style3:   closure_3.1 = AbnerPei_3.1
     style3:   out_3.1 = AbnerPei_3.1
     */
}

/// 3.2、在闭包内对该变量进行修改
func capturingValue_Test3_2() {
    let person = PC_Person()
    let style3_2_closure = {
        person.name = "AbnerPei_3.2"
        print("\n\nstyle3:   closure_3.2 = \(person.name)")
    }
    style3_2_closure()
    print("style3:   out_3.2 = \(person.name)")
    
    /**
     style3:   closure_3.2 = AbnerPei_3.2
     style3:   out_3.2 = AbnerPei_3.2
     */
}


/// PC: Primer Closure
class PC_Person {
    var name: String = "jianbo.pei"
}




